package com.loong.life.handler;

import com.loong.common.load.feidao.config.FeiDaoChargeConfig;
import com.loong.common.domain.Pager;
import com.loong.common.enumerate.PhoneChargeStatus;
import com.loong.common.load.param.OrderOrBalanceQueryParam;
import com.loong.common.load.result.AccountBalanceQueryResult;
import com.loong.common.load.result.OrderQueryResult;
import com.loong.common.load.param.OrderParam;
import com.loong.common.load.utils.PhoneChargeUtil;
import com.loong.common.utils.TransformUtils;
import com.loong.common.utils.UUIDUtils;
import com.loong.life.business.PhoneChargeRecordBusiness;
import com.loong.life.common.backend.param.ChargeIdAndOrderNumParam;
import com.loong.life.common.backend.param.PhoneChargeQueryParam;
import com.loong.life.common.backend.result.AccountBalanceResult;
import com.loong.life.common.backend.result.PhoneChargeResult;
import com.loong.life.common.forehead.param.PhoneChargeRecordForeheadParam;
import com.loong.life.common.forehead.param.PhoneChargeQueryForeheadParam;
import com.loong.life.common.forehead.result.AgentForeheadResult;
import com.loong.life.common.forehead.result.AgentProductForeheadResult;
import com.loong.life.common.forehead.result.ChargeDetailRecordForeheadResult;
import com.loong.life.common.forehead.result.PhoneChargeForeheadResult;
import com.loong.life.configuration.PhoneChargeConfiguration;
import com.loong.life.model.PhoneChargeRecord;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Date;

/**
 * @Description: 处理有关手机充值业务的handler
 * @Author: 刘群
 * @Date: 2020/11/26 16:38
 */
@Slf4j
@Service
public class PhoneChargeHandler {

    @Resource
    private PhoneChargeRecordBusiness phoneChargeBusiness;

    @Resource
    private PhoneChargeUtil phoneChargeUtil;

    @Resource
    private AgentInformationHandler agentHandler;

    @Resource
    private AgentProductHandler productHandler;

    @Resource
    private PhoneChargeConfiguration phoneChargeConfiguration;

    /**
     * 前台创建手机充值订单
     * @param param 手机充值记录参数
     */
    public void foreheadCreatePhoneChargeOrder(PhoneChargeRecordForeheadParam param) {
        param.setCreateTime(new Date());
        param.setChargeStatus(PhoneChargeStatus.WAIT_FOR_PAYMENT.getCode());//充值状态为等待付款
        String orderNum = "XSL" + UUIDUtils.getUUID();
        param.setOrderNum(orderNum);//设置订单编号
        phoneChargeBusiness.save(TransformUtils.transform(param, PhoneChargeRecord.class));
    }

    /**
     * 前台取消订单
     * @param id 手机充值记录id
     */
    public void foreheadCancelPhoneChargeOrder(Long id) {
        PhoneChargeRecordForeheadParam param = PhoneChargeRecordForeheadParam.builder()
                .id(id)
                .chargeStatus(PhoneChargeStatus.CANCEL_ORDER.getCode())//订单取消
                .lastUpdateTime(new Date())
                .build();
        phoneChargeBusiness.updateByPrimaryKeySelective(TransformUtils.transform(param, PhoneChargeRecord.class));
    }

    /**
     * 前台用户付款超时，则自动关闭交易
     * @param id 手机充值记录id
     */
    public void foreheadClosePhoneChargeTrade(Long id) {
        PhoneChargeRecordForeheadParam param = PhoneChargeRecordForeheadParam.builder()
                .id(id)
                .chargeStatus(PhoneChargeStatus.CLOSE_TRADE.getCode())//交易关闭
                .lastUpdateTime(new Date())
                .build();
        phoneChargeBusiness.updateByPrimaryKeySelective(TransformUtils.transform(param, PhoneChargeRecord.class));
    }

    /**
     * 前台根据id查找手机充值记录
     * @param id 充值记录id
     * @return 手机充值记录结果
     */
    public ChargeDetailRecordForeheadResult foreheadFindPhoneChargeRecordById(Long id) {
        //获取充值记录
        PhoneChargeRecord chargeRecord = phoneChargeBusiness.findById(id);
        if (ObjectUtils.isEmpty(chargeRecord)) return null;
        //根据充值记录的代理商id查询代理商
        AgentForeheadResult agent = agentHandler.foreheadFindAgentById(chargeRecord.getAgentId());
        //根据充值记录的产品id查询代理商产品
        AgentProductForeheadResult agentProduct = productHandler.findAgentProductById(chargeRecord.getProductId());
        if (ObjectUtils.isEmpty(agent) || ObjectUtils.isEmpty(agentProduct)) return null;
        //封装结果
        return ChargeDetailRecordForeheadResult.builder()
                .agentName(agent.getAgentName())
                .productCode(agentProduct.getProductCode())
                .chargeResult(TransformUtils.transform(chargeRecord,PhoneChargeForeheadResult.class))
                .build();
    }

    /**
     * 后台根据id查找手机充值记录
     * @param id 充值记录id
     * @return 手机充值记录结果
     */
    public PhoneChargeResult findPhoneChargeRecordById(Long id) {
        PhoneChargeRecord chargeRecord = phoneChargeBusiness.findById(id);
        if (ObjectUtils.isEmpty(chargeRecord)) return null;
        return TransformUtils.transform(phoneChargeBusiness.findById(id), PhoneChargeResult.class);
    }

    /**
     * 前台分页查询手机充值记录
     * @param param 查询条件
     * @return 分页结果
     */
    public Pager<PhoneChargeForeheadResult> foreheadPageQueryPhoneChargeRecord(PhoneChargeQueryForeheadParam param) {
        PhoneChargeQueryParam queryParam = TransformUtils.transform(param, PhoneChargeQueryParam.class);
        //根据创建时间降序排序
        queryParam.setOrderByColumn("createTime");
        queryParam.setAscOrDesc("desc");
        Pager<PhoneChargeRecord> pager = phoneChargeBusiness.pageQuery(queryParam, () -> phoneChargeBusiness.findPhoneChargeRecordByParam(queryParam));
        return TransformUtils.transformPage(pager, PhoneChargeForeheadResult.class);
    }

    /**
     * 后台分页查询手机充值记录
     * @param param 查询条件
     * @return 分页结果
     */
    public Pager<PhoneChargeResult> pageQueryPhoneChargeRecord(PhoneChargeQueryParam param) {
        Pager<PhoneChargeRecord> pager = phoneChargeBusiness.pageQuery(param, () -> phoneChargeBusiness.findPhoneChargeRecordByParam(param));
        return TransformUtils.transformPage(pager, PhoneChargeResult.class);
    }

    /**
     * 前台付款成功之后进行充值
     * @param param 充值参数
     */
    //TODO 这里是当用户付完款之后，立马调用代理充值接口进行充值，
    // 之后立马调用代理商订单查询接口查询充值状态，然后更新到数据库中。
    // 调用代理商订单查询接口查询充值状态，应该是不仅仅只在这里调用一次，还需要再别的地方再次调用
    public void foreheadPaidSuccessThenPhoneCharge(PhoneChargeRecordForeheadParam param) {
        //获取FeiDao充值的配置
        FeiDaoChargeConfig feiDaoChargeConfig = phoneChargeConfiguration.getFeiDaoChargeConfig();
        //根据代理商产品id查询出产品
        AgentProductForeheadResult agentProduct = productHandler.findAgentProductById(param.getProductId());
        //封装充值订单参数
        OrderParam orderParam = OrderParam.builder()
                .uid(feiDaoChargeConfig.getUid())
                .authKey(feiDaoChargeConfig.getAuthKey())
                .orderId(param.getOrderNum())
                .phone(param.getPhoneNumber())
                .pcode(agentProduct.getProductCode())
                .money(agentProduct.getDiscountPrice())
                .build();
        //调用代理商的下单接口进行充值
        phoneChargeUtil.createOrder(orderParam);
        //更新手机的充值状态
        this.commonUpdateChargeStatus(feiDaoChargeConfig,param.getOrderNum(),param.getId());
    }

    /**
     * 后台更新手机的充值状态
     * @param param 充值id和订单编号封装的参数
     */
    public void updatePhoneChargeStatus(ChargeIdAndOrderNumParam param){
        FeiDaoChargeConfig feiDaoChargeConfig = phoneChargeConfiguration.getFeiDaoChargeConfig();
        this.commonUpdateChargeStatus(feiDaoChargeConfig,param.getOrderNum(),param.getChargeId());
    }

    /**
     * 公共方法：更新手机的充值状态
     * @param feiDaoChargeConfig FeiDao充值配置参数
     * @param orderNum 订单编号
     * @param chargeRecordId 充值记录id
     */
    private void commonUpdateChargeStatus(FeiDaoChargeConfig feiDaoChargeConfig, String orderNum, Long chargeRecordId){
        //封装订单查询参数
        OrderOrBalanceQueryParam orderOrBalanceQueryParam = OrderOrBalanceQueryParam.builder()
                .uid(feiDaoChargeConfig.getUid())
                .authKey(feiDaoChargeConfig.getAuthKey())
                .orderId(orderNum)
                .build();
        //调用订单查询接口查询充值订单
        OrderQueryResult orderQueryResult = phoneChargeUtil.queryOrder(orderOrBalanceQueryParam);
        //封装手机充值记录的参数
        PhoneChargeRecord chargeRecord = new PhoneChargeRecord();
        chargeRecord.setId(chargeRecordId);
        chargeRecord.setLastUpdateTime(new Date());
        if (ObjectUtils.isNotEmpty(orderQueryResult)){
            //通过订单查询结果获得充值状态
            String chargeStatus = orderQueryResult.getRechargeState();
            int statusCode = PhoneChargeStatus.getPhoneChargeStatusCode(chargeStatus);
            chargeRecord.setChargeStatus(statusCode);
        }
        //更新手机充值记录的充值状态
        phoneChargeBusiness.updateByPrimaryKeySelective(chargeRecord);
    }

    /**
     * 查询应用在代理商中的余额
     * @param date 查询时间
     * @return 账户余额结果
     */
    public AccountBalanceResult findAccountBalanceInAgent(Date date){
        //获取FeiDao充值的配置
        FeiDaoChargeConfig feiDaoChargeConfig = phoneChargeConfiguration.getFeiDaoChargeConfig();
        //封装余额查询参数
        OrderOrBalanceQueryParam balanceQueryParam = OrderOrBalanceQueryParam.builder()
                .uid(feiDaoChargeConfig.getUid())
                .timestamp(date.getTime())
                .authKey(feiDaoChargeConfig.getAuthKey())
                .build();
        AccountBalanceQueryResult result = phoneChargeUtil.queryBalance(balanceQueryParam);
        if (ObjectUtils.isEmpty(result)) return null;
        return TransformUtils.transform(result,AccountBalanceResult.class);
    }
}
